using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;

namespace ProxyServer.Pool
{
    public class SocketAsyncEventPool
    {
        private readonly Stack<SocketAsyncEventArgs> pool;
        private readonly BuffManager buffManager;
        private readonly Semaphore semaphore;

        public SocketAsyncEventPool(int capacity, BuffManager buffManager)
        {
            this.buffManager = buffManager;

            pool = new Stack<SocketAsyncEventArgs>(capacity);

            for (var i = 0; i < capacity; i++)
            {
                pool.Push(new SocketAsyncEventArgs());
            }

            semaphore = new Semaphore(capacity, capacity);
        }

        public SocketAsyncEventArgs Pop(bool withCache)
        {
            semaphore.WaitOne();

            var args = pool.Pop();

            if (withCache)
            {
                buffManager.SetBuffer(args);
            }

            return args;
        }

        public void Push(SocketAsyncEventArgs item)
        {
            pool.Push(item);

            if (item.Buffer != null)
            {
                buffManager.FreeBuffer(item);
            }
            
            semaphore.Release();
        }
    }
}